#!/usr/bin/env python3
# -*- coding: utf-8 -*-


# useful for handling different item types with a single interface
from pymysql import cursors
from twisted.enterprise import adbapi
import json
class GostudyPipeline(object):
    # 函数初始化
    def __init__(self, db_pool):
        self.db_pool = db_pool

    @classmethod
    def from_settings(cls, settings):
        """类方法，只加载一次，数据库初始化"""
        db_params = dict(
            host=settings['MYSQL_HOST'],
            user=settings['MYSQL_USER'],
            password=settings['MYSQL_PASSWORD'],
            port=settings['MYSQL_PORT'],
            database=settings['MYSQL_DBNAME'],
            charset=settings['MYSQL_CHARSET'],
            use_unicode=True,
            # 设置游标类型
            cursorclass=cursors.DictCursor
        )
        # 创建连接池
        db_pool = adbapi.ConnectionPool('pymysql', **db_params)
        # 返回一个pipeline对象
        return cls(db_pool)
    def process_item(self, item, spider):
        """
               数据处理
               :param item:
               :param spider:
               :return:
        """
        # 把要执行的sql放入
        myitem = {}
        myitem['save_data'] = item['save_data']
        if 'table' in item:
            myitem['table'] = item['table']
        if 'del_fail_record' in item:
            myitem['del_fail_record'] = item['del_fail_record']
        query = self.db_pool.runInteraction(self.insert_intoall, myitem)

        # 如果sql执行发送错误,自动回调addErrBack()函数
        query.addErrback(self.handle_error, myitem, spider)
        return myitem
        # 处理sql函数
    def insert_intoall(self, cursor, item):
        # 执行sql语句
        saveitem = item['save_data']
        if 'table' in item:
            if item['table'] == 'fail':
                saveitem[1] = json.dumps(saveitem[1])
                cursor.execute('insert into fail_record (url, parent_data, deep) values (%s, %s, %s )', saveitem)
            else:
                #这边是错误重新执行 保存操作
                cursor.executemany('insert into area (id, deep, pid, name) values (%s, %s , %s ,%s)', saveitem)
                #执行成功后删除已经存在错误链接
                cursor.execute('delete from fail_record where url=%s', item['del_fail_record'])

        else:
            cursor.executemany('insert into area (id, deep, pid, name) values (%s, %s , %s ,%s)', saveitem)
        # 错误函数

    def handle_error(self, failure, item, spider):
        # #输出错误信息
        print("failure", failure)
